package bean.dao;
import java.util.*;

import hbt.HibernateUtil;
import org.hibernate.*;

import bean.*;

public class RemitoDAO {
	private static RemitoDAO instancia = null;
	private static SessionFactory sf = null;

	public static RemitoDAO getInstancia(){
		if(instancia == null){
			sf = HibernateUtil.getSessionFactory();
			instancia = new RemitoDAO();
		} 
		return instancia;
	}
	
	
	public Remito buscarRemito (String cuil){
		Remito remito = new Remito();
		Session session = sf.openSession();
		Query query = session.createQuery("from Remito r where r.cliente.cuil=:cuil");
		query.setParameter("cuil", cuil);
		remito = (Remito) query.uniqueResult();
		session.close();
		return remito;
	}
	
	//guarda los movimientos de ingreso de mercaderia en la base
	public void recibirMercaderiaProveedor(String archivo){
		ArrayList <Movimiento> movimientos = XmlDAO.getInstancia().recibirMercaderiaProveedor(archivo);
		for (int i = 0; i< movimientos.size();i++){
			Session session = sf.openSession();
			session.beginTransaction();
			Producto producto = ProductoDAO.getInstancia().buscarProducto(movimientos.get(i).getProducto().getId().getNroSerie(), movimientos.get(i).getProducto().getId().getSufijo());
			movimientos.get(i).setProducto(producto);
			OrdenDeCompra oc = OrdenDeCompraDAO.getInstancia().buscarOrdenDeCompra(movimientos.get(i).getOrdenDeCompra().getIdOC());
			movimientos.get(i).setOrdenDeCompra(oc);
			session.save(movimientos.get(i));
			session.flush();
			session.getTransaction().commit();
			session.close();
		}
	}
	
	@SuppressWarnings("unchecked")
	public ArrayList <String> generarRemitos(){
		ArrayList <String> vectorRemitosXML = new ArrayList <String>();
		ArrayList <Remito> remitos = new ArrayList<Remito>();
		Session session = sf.openSession();
		session.beginTransaction();	
		//Busco los clientes
		List <Cliente> clientes = session.createQuery("from Cliente").list();
		for (int i =0; i<clientes.size();i++){
			//Busco las ordenes de pedido pendientes 
			Query query = session.createQuery("select odp.numOrden, odp.fechaGeneracion,odp.pendiente from OrdenDePedido odp, Cliente c, Item_OrdenDePedido oped, Cotizacion coti, SolicitudDeCotizacion sol where (odp.numOrden = oped.ordenDePedido.numOrden) and (oped.cotizacion.numCot = coti.numCot) and (coti.solicitud.id.numero = sol.id.numero) and (sol.cliente.cuil=:cuil) group by odp.numOrden, odp.fechaGeneracion,odp.pendiente");
			query.setParameter("cuil", clientes.get(i).getCuil());
			List <Object[]> ordenesDePedido = query.list();
			// Para cada orden de pedido pendiente de entrega genero un remito y busco los items pendientes
			Remito remito = new Remito();
			remito.setCliente(clientes.get(i));
			remito.setFecha(FechaDAO.getInstancia().getFechaActual());
			session.persist(remito);
			for (int j=0;j<ordenesDePedido.size();j++){
				//busco la ordenDePedido
				OrdenDePedido orden = OrdenDePedidoDAO.getInstancia().buscarOrdenDePedido((Integer)ordenesDePedido.get(j)[0]);
				//Busco los items de la orden de pedido
				Query query2 = session.createQuery("from Item_OrdenDePedido iodp where (iodp.ordenDePedido.numOrden=:numOrden) and (iodp.pendienteDeCompra = true)");
				query2.setParameter("numOrden",orden.getNumOrden());
				List<Item_OrdenDePedido> items = query2.list();
				for (int z=0; z<items.size();z++){
					Item_Remito itemRemito = new Item_Remito();
					itemRemito.setOrdenDePedido(orden);
					itemRemito.setRemito(remito);
					//busco si existe el movimiento
					Item_OrdenDePedido item = items.get(z);
					Movimiento mov = MovimientoDAO.getInstancia().buscarMovimiento(item.getProducto().getId().getNroSerie(), item.getProducto().getId().getSufijo());
					//asigno la cantidad que haya ingresado o menos
					if (mov.getCantidad() == item.getCantidadSolicitada()){
						itemRemito.setCantidadEnviada(mov.getCantidad());
						itemRemito.setProducto(item.getProducto());
						mov.setCantidad(0);
						item.setCantidadEnviada(item.getCantidadSolicitada());
						item.setPendienteDeCompra(false);
						session.persist(item);
						session.saveOrUpdate(itemRemito);
					}
					else{
						itemRemito.setCantidadEnviada(mov.getCantidad());
						itemRemito.setProducto(item.getProducto());
						item.setCantidadEnviada(mov.getCantidad());
						mov.setCantidad(0);
						session.update(item);
						session.saveOrUpdate(itemRemito);
						
					}
					
					remito.getItems().add(itemRemito);
				}
			}
			remitos.add(remito);
		}
		
		session.flush();
		session.getTransaction().commit();
		sf.close();
		
		for (int i =0; i< remitos.size();i++){
			String xmlRemito = XmlDAO.getInstancia().generarRemitos(remitos.get(i));
			vectorRemitosXML.add(xmlRemito);
		}
		return vectorRemitosXML;
	}
	
	
}
